package com.example.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.example.article.mapper.ArticleContentMapper;
import com.example.article.mapper.ArticleMapper;
import com.example.article.service.ArticleFreemarkerService;
import com.example.file.service.FileStorageService;
import com.example.model.article.pojo.Article;
import com.example.model.article.pojo.ArticleContent;
import com.example.model.search.pojo.SearchArticleVo;
import freemarker.template.Configuration;
import freemarker.template.Template;
import io.seata.common.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

import static com.example.common.constants.ArticleConstants.TOPIC_SYNC_ES;

@Service
@Slf4j
public class ArticleFreemarkerServiceImpl implements ArticleFreemarkerService {
    @Autowired
    private ArticleContentMapper articleContentMapper;
    @Autowired
    private Configuration configuration;
    @Autowired
    private FileStorageService fileStorageService;
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;

    @Override
    @Transactional
    public Boolean buildArticleToMinIO(Long articleId) {
        // 1、获取文章内容
        ArticleContent articleContent = articleContentMapper.selectOne(Wrappers.<ArticleContent>lambdaQuery().eq(ArticleContent::getArticleId, articleId));
        if (articleContent == null && StringUtils.isNotBlank(articleContent.getArticleContent())) {
            // 2、通过freemark生成html文件
            InputStream inputStream = null;
            try {
                Template template = configuration.getTemplate("article.ftl");
                // 合成
                Map<String, Object> map = new HashMap<>();
                map.put("content", articleContent.getArticleContent());
                StringWriter stringWriter = new StringWriter();
                template.process(map, stringWriter);
                inputStream = new ByteArrayInputStream(stringWriter.toString().getBytes());
            } catch (Exception e) {
                e.printStackTrace();
                log.info("文章生成失败，文章ID：{}", articleId);
                return false;
            }

            // 3、上传到minio
            String path = fileStorageService.uploadHtmlFile("", articleContent.getArticleId() + ".html", inputStream);
            // 4、更新文章表中的html_url字段
            Article article = articleMapper.selectById(articleContent.getArticleId());
            // 查看之前是否存在url，如果存在，则删除
            if (StringUtils.isNotBlank(article.getStaticUrl())) {
                fileStorageService.delete(article.getStaticUrl());
            }
            article.setStaticUrl(path);
            articleMapper.updateById(article);
            log.info("文章生成成功，文章ID：{}", articleId);
            syncToEs(article, articleContent);
        }
        return true;
    }

    /**
     * 同步文章的ES，通过MQ
     * @param article
     * @param articleContent
     */
    private void syncToEs(Article article, ArticleContent articleContent) {
        try {
            SearchArticleVo searchArticleVo = new SearchArticleVo();
            BeanUtils.copyProperties(article, searchArticleVo);
            searchArticleVo.setArticleContent(articleContent.getArticleContent());
            kafkaTemplate.send(TOPIC_SYNC_ES, JSON.toJSONString(searchArticleVo));
        } catch (Exception e) {
            e.printStackTrace();
            log.error("同步文章到ES失败，文章ID：{}", e);
        }
    }
}
